package bdz.common.managers
{
	import bdz.common.events.UploadManagerEvent;
	
	import flash.events.DataEvent;
	import flash.events.Event;
	import flash.events.ProgressEvent;
	import flash.net.FileFilter;
	import flash.net.FileReference;
	import flash.net.URLRequest;
	import flash.net.URLVariables;
	/**
	 * Upload Manager is an extension of the built-in FileReference object in Actionscript 3.
	 * It is designed to simplify browsing of files to upload by providing preset
	 * and allows organization of the variables being passed and received from the server.
	 */
	public class UploadManager extends FileReference
	{
		private var baseURL:String
		private var uploadVariables:URLVariables;
		private var uploadRequest:URLRequest;

		function UploadManager():void{
			uploadVariables = new URLVariables();
			addEventListener(Event.OPEN, onFileOpen);
			addEventListener(ProgressEvent.PROGRESS, onFileProgress);
			addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, onFileUploaded);
		}
		/**
			 * Alternative upload complete event with 
			 * essential data passed on its generic event.
			 * Does not override standard event being dispatched 
			 * and can still be listened as normal.
			 */
		private function onFileUploaded(evt:DataEvent):void {
			var dataProxy:Object = new Object();
			
			dataProxy.serverReply = evt.data;
			dataProxy.variables = uploadVariables;
			dataProxy.url = uploadRequest.url;
			dispatchEvent(new UploadManagerEvent(UploadManagerEvent.UPLOAD_COMPLETE, dataProxy));
		}
		/**
			 * Alternative upload progress event
			 * with additional information passed on its generic event
			 * Does not override standard event being dispatched 
			 * and can still be listened to as normal.
			 */
		private function onFileProgress(evt:ProgressEvent):void{
			
			var dataToPass:Object = new Object();
			dataToPass.totalPercent = int((evt.bytesLoaded/evt.bytesTotal)*100);
			dataToPass.bytesLoaded = evt.bytesLoaded;
			dataToPass.bytesTotal = evt.bytesTotal;
			dispatchEvent(new UploadManagerEvent(UploadManagerEvent.UPLOAD_PROGRESS, dataToPass));
		}
		private function onFileOpen(evt:Event):void {
			dispatchEvent(new UploadManagerEvent(UploadManagerEvent.UPLOAD_START, null));
		}
		/**
		 * A shortcut implementation for browsing images
		 * without knowing the file filter implementation
		 * can also be applied to other file types such as documents 
		 * and custom file set.
		 * 
		 */
		public function browseForImage():void{
			browse([new FileFilter("Images", "*.jpg;*.gif;*.png")]);
		}
		/**
		 * A shortcut implementation for browsing documents
		 * without knowing the file filter implementation
		 * can also be applied to other file types such as images 
		 * and custom file set.
		 * 
		 */
		public function browseForCustomType(tlabel:String, ftypes:String):void{
			browse([new FileFilter(tlabel, ftypes)]);
		}
		public function browseForDocuments():void{
			browse([new FileFilter("Documents", "*.doc;*.rtf;*.txt;*.xls;*.pdf")]);
		}
		/**
		 * A shortcut implementation for browsing flash video
		 * without knowing the file filter implementation
		 * can also be applied to other file types such as images 
		 * and custom file set.
		 * 
		 */
		public function browseForFLV():void{
			browse([new FileFilter("Flash Video", "*.flv")]);
		}
		/**
		 * A shortcut implementation for browsing all files
		 * without setting the file filter implementation.
		 * 
		 */
		public function browseAllTypes():void{
			browse([new FileFilter("Any file types", "*.*")]);
		}
		/**
		 * Adds additional variables to be passed on the upload
		 * target url.
		 */
		public function addVariables(prop:String, value:*):void{
			uploadVariables[prop] = value;
		}
		/**
		 * Invokes the upload process and 
		 * passess all the variables attached to the 
		 * UploadManager Object.
		 */
		public function uploadFile():void{
			uploadRequest.data = uploadVariables || null;
			upload(uploadRequest);
		}
		/**
		 * A method that maybe used if you want a custom
		 * request object to be used the the UploadManager class.
		 */
		public function set request(req:URLRequest):void{
			uploadRequest = req;
		}
		
		/**
		 * Sets the URL where the UploadManager will connect
		 * to when downloading/uploading files.
		 */
		public function set url(u:String):void{
			baseURL = u;
			uploadRequest = new URLRequest(baseURL);
			uploadRequest.method = "POST";
		}
		public function get url():String{
			return baseURL;
		}
		/**
		 * Sets the method to be used by the URLRequest object 
		 * that will handle the connection to be made by the UploadManager.
		 * 
		 */
		public function set method(m:String):void{
			uploadRequest.method = m;
		}
		public function get method():String{
			return uploadRequest.method;
		}
		
		/**
		 * A shortcut implementation of setting the variables to be 
		 * passed when invoking the upload process.
		 */
		public function set variables(v:URLVariables):void{
			uploadVariables = v;
		}
		public function get variables():URLVariables{
			return uploadVariables;
		}

	}
}